package me.itsoo.artemis.framework.ioc.bean;

import lombok.Getter;
import lombok.Setter;

import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;

/**
 * BeanDefinition
 *
 * @author zxy
 * @version 0.0.1
 * @since 2023/6/2
 */
public class BeanDefinition {

    /**
     * Bean 名称
     */
    @Getter
    private final String beanName;

    /**
     * Bean 类型
     */
    @Getter
    private final Class<?> beanClass;

    /**
     * Bean 别名
     */
    @Getter
    private final Set<String> aliasNames = new LinkedHashSet<>();

    /**
     * 循环依赖标识
     */
    @Getter
    @Setter
    private boolean isCircularDependency = false;

    /**
     * 配置类标识
     */
    @Getter
    @Setter
    private boolean isConfig = false;

    /**
     * Bean 依赖
     */
    @Getter
    @Setter
    private Set<BeanDefinition> beanDependencies = new LinkedHashSet<>();

    /**
     * 创建状态标识（默认待创建）
     */
    private BeanFlashStatus beanFlashStatus = BeanFlashStatus.WAITING;

    /**
     * 注入方式标识（默认构造）
     */
    private BeanInjectType beanInjectType = BeanInjectType.CONSTRUCTOR;

    public BeanDefinition(String beanName, Class<?> beanClass) {
        this.beanName = beanName;
        this.beanClass = beanClass;
    }

    /**
     * 设置别名
     *
     * @param aliasName String
     */
    public void setAliasName(String aliasName) {
        aliasNames.add(aliasName);
    }

    /**
     * 添加依赖
     *
     * @param beanDefinition BeanDefinition
     */
    public void appendDependency(BeanDefinition beanDefinition) {
        beanDependencies.add(beanDefinition);
    }

    /**
     * 待创建
     *
     * @return boolean
     */
    public boolean isWaiting() {
        return BeanFlashStatus.WAITING.isEquals(beanFlashStatus);
    }

    /**
     * 创建中
     *
     * @return boolean
     */
    public boolean isCreating() {
        return BeanFlashStatus.CREATING.isEquals(beanFlashStatus);
    }

    /**
     * 已创建
     *
     * @return boolean
     */
    public boolean isFinished() {
        return BeanFlashStatus.FINISHED.isEquals(beanFlashStatus);
    }

    /**
     * 置为待创建
     */
    public void setWaiting() {
        if (Objects.isNull(beanFlashStatus) || isWaiting()) {
            beanFlashStatus = BeanFlashStatus.WAITING;
        }
    }

    /**
     * 置为创建中
     */
    public void setCreating() {
        if (isWaiting()) {
            beanFlashStatus = BeanFlashStatus.CREATING;
        }
    }

    /**
     * 置为已创建
     */
    public void setFinished() {
        if (isCreating()) {
            beanFlashStatus = BeanFlashStatus.FINISHED;
        }
    }

    /**
     * 构造方式
     *
     * @return boolean
     */
    public boolean isConstructorType() {
        return BeanInjectType.CONSTRUCTOR.isEquals(beanInjectType);
    }

    /**
     * 方法方式
     *
     * @return boolean
     */
    public boolean isMethodType() {
        return BeanInjectType.METHOD.isEquals(beanInjectType);
    }

    /**
     * 字段方式
     *
     * @return boolean
     */
    public boolean isFieldType() {
        return BeanInjectType.FIELD.isEquals(beanInjectType);
    }

    /**
     * 置为构造方式
     */
    public void setConstructorType() {
        this.beanInjectType = BeanInjectType.CONSTRUCTOR;
    }

    /**
     * 置为方法方式
     */
    public void setMethodType() {
        this.beanInjectType = BeanInjectType.METHOD;
    }

    /**
     * 置为字段方式
     */
    public void setFieldType() {
        this.beanInjectType = BeanInjectType.FIELD;
    }

    @Override
    public int hashCode() {
        return Objects.hash(beanClass, beanName);
    }

    @Override
    public boolean equals(Object obj) {
        return (obj instanceof BeanDefinition)
                && Objects.equals(this.beanClass, ((BeanDefinition) obj).beanClass)
                && Objects.equals(this.beanName, ((BeanDefinition) obj).beanName);
    }
}
